package com.ruoyi.web.controller.websocket;

import com.ruoyi.common.utils.JacksonUtils;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用于向客户端推送消息
 */
@Slf4j
@ServerEndpoint("/notify")
@Api(tags = "客户端消息推送")
@Component
@RequiredArgsConstructor
public class SyncWebSocketController {

    private static final Map<String, Session> SESSIONS = new ConcurrentHashMap<>();

    private static final Map<Integer, Set<String>> COMMAND_SESSION_IDS = new ConcurrentHashMap<>();

    public static void sendMessage(int command, String message) {
        final String messageContent = new NextMessage(command, null, message).toJacksonString();
        SESSIONS.values().forEach(session -> {
            try {
                session.getBasicRemote().sendText(messageContent);
            } catch (IOException e) {
                log.error("发送指令[{}]对应命令[{}]发生错误", command, messageContent, e);
            }
        });
    }

    @OnOpen
    public void onOpen(Session session) {
        SESSIONS.put(session.getId(), session);
    }

    @OnClose
    public void onClose(Session session) {
        SESSIONS.remove(session.getId());
    }

    @OnError
    public void onError(Session session, Throwable t) {
        log.info("websocket连接[{}]发生异常", session.getId(), t);
        onClose(session);
    }

    @OnMessage
    public void onMessage(Session session, String message) {
    }

    @Data
    public static final class SubCommand {

        private int subCommand;

    }

    public record NextMessage(int command, String message, Object data) {

        public String toJacksonString() {
            return JacksonUtils.writeValueAsString(this);
        }

    }
}
